﻿//------------------------------------------------------------------------------
// <copyright company="Tunynet">
//     Copyright (c) Tunynet Inc.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using Tunynet.Events;
using Tunynet.Logging;

namespace Tunynet.Common
{
    /// <summary>
    /// 勋章创建和删除的事件
    /// </summary>
    public class MedalEventModule : IEventMoudle
    {
        private MedalService medalService;
        private AttachmentService attachmentService = new AttachmentService(TenantTypeIds.Instance().Medal());
        private IKvStore kvStore;
        private RoleService roleService;
        private OperationLogService operationLogService;
        private NoticeService noticeService;
        private INoticeSender noticeSender;

        //构造
        public MedalEventModule(MedalService medalService, IKvStore kvStore, RoleService roleService, OperationLogService operationLogService, NoticeService noticeService, INoticeSender noticeSender)
        {
            this.medalService = medalService;
            this.kvStore = kvStore;
            this.roleService = roleService;
            this.operationLogService = operationLogService;
            this.noticeService = noticeService;
            this.noticeSender = noticeSender;
        }

        /// <summary>
        /// 注册事件处理程序
        /// </summary>
        public void RegisterEventHandler()
        {
            EventBus<Medal>.Instance().After += new CommonEventHandler<Medal, CommonEventArgs>(MedalOperation_After);
            EventBus<MedalToUser>.Instance().After += new CommonEventHandler<MedalToUser, CommonEventArgs>(MedalToUserOperation_After);
        }

        /// <summary>
        /// 勋章事件
        /// </summary>
        /// <param name="comment"></param>
        /// <param name="eventArgs"></param>
        private void MedalOperation_After(Medal medal, CommonEventArgs eventArgs)
        {
            var userInfo = eventArgs.OperatorInfo;
            //日志
            OperationLog newLog = new OperationLog(eventArgs.OperatorInfo);
            newLog.OperationObjectId = medal.MedalId;
            newLog.OperationObjectName = medal.MedalName;
            newLog.OperationType = eventArgs.EventOperationType;
            newLog.TenantTypeId = TenantTypeIds.Instance().Medal();
            newLog.OperationUserRole = string.Join(",", roleService.GetRoleNamesOfUser(userInfo.OperationUserId));

            if (eventArgs.EventOperationType == EventOperationType.Instance().Create())
            {
                newLog.Description = $"{userInfo.Operator}添加勋章:{medal.MedalName}";

                //将临时附件转换为正式附件
                List<long> attachmentId = new List<long>();
                attachmentId.Add(medal.ImageAttachmentId);
                attachmentService.ToggleTemporaryAttachments(userInfo.OperationUserId, TenantTypeIds.Instance().Medal(), medal.MedalId, attachmentId);

                //设置互斥组
                if (medal.GroupId > 0)
                {
                    MedalInGroup medalInGroup = MedalInGroup.New();
                    medalInGroup.MedalId = medal.MedalId;
                    medalInGroup.GroupId = medal.GroupId;
                    medalService.CreateMedalInGroup(medalInGroup);
                }
                //设置勋章条件
                if (medal.AwardType == AwardType.AwardBySelf && medal.Conditions.Length > 0)
                {
                    var conditionIds = medal.Conditions.Split(',');
                    var conditionValues = medal.ConditionValues.Split(',');
                    for (int i = 0; i < conditionIds.Length; i++)
                    {
                        var conditionId = conditionIds[i];
                        var conditionValue = conditionValues[i];

                        MedalInCondition medalInCondition = MedalInCondition.New();
                        medalInCondition.ConditionId = Convert.ToInt64(conditionId);
                        medalInCondition.MedalId = medal.MedalId;
                        medalInCondition.MinCondition = Convert.ToInt32(conditionValue);
                        medalService.CreateMedalInCondition(medalInCondition);
                    }
                }
            }
            else if (eventArgs.EventOperationType == EventOperationType.Instance().Update())
            {
                newLog.Description = $"{userInfo.Operator}更新勋章:{medal.MedalName}";
                //将临时附件转换为正式附件
                List<long> attachmentId = new List<long>();
                attachmentId.Add(medal.ImageAttachmentId);
                attachmentService.ToggleTemporaryAttachments(userInfo.OperationUserId, TenantTypeIds.Instance().Medal(), medal.MedalId, attachmentId);

                //删除互斥组设置
                medalService.DeleteMedalInGroupByMedalId(medal.MedalId);
                //设置互斥组
                if (medal.GroupId > 0)
                {
                    MedalInGroup medalInGroup = MedalInGroup.New();
                    medalInGroup.MedalId = medal.MedalId;
                    medalInGroup.GroupId = medal.GroupId;
                    medalService.CreateMedalInGroup(medalInGroup);
                }
                //删除条件设置
                medalService.DeleteMedalInConditionByMedalId(medal.MedalId);
                //设置勋章条件
                if (medal.AwardType == AwardType.AwardBySelf && medal.Conditions.Length > 0)
                {
                    var conditionIds = medal.Conditions.Split(',');
                    var conditionValues = medal.ConditionValues.Split(',');
                    for (int i = 0; i < conditionIds.Length; i++)
                    {
                        var conditionId = conditionIds[i];
                        var conditionValue = conditionValues[i];

                        MedalInCondition medalInCondition = MedalInCondition.New();
                        medalInCondition.ConditionId = Convert.ToInt64(conditionId);
                        medalInCondition.MedalId = medal.MedalId;
                        medalInCondition.MinCondition = Convert.ToInt32(conditionValue);
                        medalService.CreateMedalInCondition(medalInCondition);
                    }
                }
            }
            else if (eventArgs.EventOperationType == EventOperationType.Instance().Delete())
            {
                newLog.Description = $"{userInfo.Operator}删除勋章:{medal.MedalName}";
                //删除附件
                attachmentService.DeletesByAssociateId(medal.MedalId);
                //删除设置的互斥组
                medalService.DeleteMedalInGroupByMedalId(medal.MedalId);
                //删除条件设置
                medalService.DeleteMedalInConditionByMedalId(medal.MedalId);
                //删除该勋章的授予记录
                medalService.DeleteMedaltoUserByMedalId(medal.MedalId);
            }
            if (medal.GroupIdBefore > 0)
            {
                //设置互斥组勋章数
                MedalGroup medalGroup = medalService.GetGroup(medal.GroupIdBefore);
                medalGroup.MeadlCount = medalService.GetMedalCount(medal.GroupIdBefore);
                medalService.UpdateGroup(medalGroup);
            }
            if (medal.GroupId > 0)
            {
                //设置互斥组勋章数
                MedalGroup medalGroup = medalService.GetGroup(medal.GroupId);
                medalGroup.MeadlCount = medalService.GetMedalCount(medal.GroupId);
                medalService.UpdateGroup(medalGroup);
            }
            //写入日志
            operationLogService.Create(newLog);
        }

        /// <summary>
        /// 授予勋章事件
        /// </summary>
        /// <param name="comment"></param>
        /// <param name="eventArgs"></param>
        private void MedalToUserOperation_After(MedalToUser medaltoUser, CommonEventArgs eventArgs)
        {
            var userInfo = eventArgs.OperatorInfo;
            var medal = medalService.Get(medaltoUser.MedalId);
            medal.GroupId = medalService.GetGroupId(medal.MedalId);
            //发送通知
            Notice notice = Notice.New();
            notice.ReceiverId = medaltoUser.UserId;
            notice.RelativeObjectName = medaltoUser.GetMedalInfo().MedalName;
            if (eventArgs.EventOperationType == EventOperationType.Instance().Create())
            {
                if (medaltoUser.UserAwardStatus == UserAwardStatus.AlreadyAward)
                {
                    if (userInfo.OperationUserId != medaltoUser.UserId)
                    {
                        //发送通知(勋章申请通过审核)
                        notice.NoticeTypeKey = NoticeTypeKeys.Instance().MedalAward();
                    }
                    //如果授予状态为已授予，则计数+1
                    kvStore.Increase(KvKeys.Instance().MedaltoUser(medaltoUser.MedalId));
                    //如果是互斥组勋章，则删除用户互斥组中的其他勋章
                    if (medal.GroupId > 0)
                    {
                        var medaltoUserId = medalService.GetMedaltoUserByGroupId(medal.GroupId, medaltoUser.UserId);
                        if (medaltoUserId > 0 && medaltoUserId != medaltoUser.Id)
                            medalService.DeleteMedalToUser(medaltoUserId);
                    }
                }
            }
            else if (eventArgs.EventOperationType == EventOperationType.Instance().Update())
            {
                //更新勋章授予用户计数
                if (medaltoUser.UserAwardStatus != medaltoUser.UserAwardStatusBefore)
                {
                    if (medaltoUser.UserAwardStatusBefore == UserAwardStatus.AlreadyAward)
                    {
                        if (medaltoUser.UserAwardStatus == UserAwardStatus.Recovered && userInfo.OperationUserId != medaltoUser.UserId)
                        {
                            //发送通知(勋章被收回)
                            notice.NoticeTypeKey = NoticeTypeKeys.Instance().MedalRecovered();
                        }
                        //如果更新之前为已授予，现在为其他状态则计数减1
                        kvStore.Increase(KvKeys.Instance().MedaltoUser(medaltoUser.MedalId), -1);
                    }
                    if (medaltoUser.UserAwardStatus == UserAwardStatus.AlreadyAward)
                    {
                        //如果更新状态为已授予，并且之前为其他状态则计数+1
                        kvStore.Increase(KvKeys.Instance().MedaltoUser(medaltoUser.MedalId), 1);
                        if (userInfo.OperationUserId != medaltoUser.UserId)
                        {
                            if (medaltoUser.UserAwardStatusBefore == UserAwardStatus.Applying)
                            {
                                //发送通知(勋章申请通过审核)
                                notice.NoticeTypeKey = NoticeTypeKeys.Instance().MedalApproved();
                            }
                            else
                            {
                                //发送通知(勋章申请通过审核)
                                notice.NoticeTypeKey = NoticeTypeKeys.Instance().MedalAward();
                            }
                        }
                        //如果是互斥组勋章，则删除用户互斥组中的其他勋章
                        if (medal.GroupId > 0)
                        {
                            var medaltoUserId = medalService.GetMedaltoUserByGroupId(medal.GroupId, medaltoUser.UserId);
                            if (medaltoUserId > 0 && medaltoUserId != medaltoUser.Id)
                                medalService.DeleteMedalToUser(medaltoUserId);
                        }
                    }
                    if (medaltoUser.UserAwardStatus == UserAwardStatus.Refused && userInfo.OperationUserId != medaltoUser.UserId)
                    {
                        //发送通知(勋章申请被拒绝)
                        notice.NoticeTypeKey = NoticeTypeKeys.Instance().MedalDisapproved();
                    }
                }
            }
            else if (eventArgs.EventOperationType == EventOperationType.Instance().Delete())
            {
                if (medaltoUser.UserAwardStatus == UserAwardStatus.AlreadyAward)
                {
                    //删除时状态为已授予则计数减1
                    kvStore.Increase(KvKeys.Instance().MedaltoUser(medaltoUser.MedalId), -1);
                }
            }
            //发生通知
            if (!string.IsNullOrEmpty(notice.NoticeTypeKey))
            {
                noticeService.Create(notice);
                noticeSender.Send(notice);
            }
        }
    }
}